context("Testing the basic operations of population object")


N=100
x=runif(N,0,100)
y=runif(N,0,200)
sp1="sp1"

test_that("Create a population object",{
  pop=population(species=sp1,x=x,y=y,plotdim=c(100,200))
  expect_is(pop,"population") # a population object
  expect_is(pop,"data.frame") #it is also a data.frame
  expect_equal(dim(pop),c(N,2)) #the same number of row
  expect_equal(attr(pop,"plotdim"),c(100,200))
  expect_equal(attr(pop,"species"),sp1)
  
  #the species parameter can only have one name for a population
  expect_error(population(species=1:2,x=x,y=y,plotdim=c(100,200)),
               "only one species name can be defined for a population")
  
  #create an empty population
  pop2=population(species = sp1,x=numeric(),y=numeric(),plotdim = c(1,1))
  expect_is(pop2,"population") # a population object
  expect_is(pop2,"data.frame") #it is also a data.frame
  expect_equal(dim(pop2),c(0,2)) #the same number of row
  expect_equal(attr(pop2,"plotdim"),c(1,1))
  
  #test the boundary condition
  bound_test=function(x=0,y=0,sp=1,plotdim=c(100,200)){
    pop=population(sp,x,y,plotdim)
  }
  expect_equal(dim(bound_test(x=0,y=0)),c(1,2))
  expect_equal(dim(bound_test(x=100,y=0)),c(1,2))
  expect_equal(dim(bound_test(x=0,y=200)),c(1,2))
  expect_equal(dim(bound_test(x=100,y=200)),c(1,2))
  
  #if location of any points overlap, warning message printed
  expect_warning(pop3<-bound_test(x=c(1,1),y=c(2,2),sp=1),
                 "Some individuals are spatilly overlapped")
  expect_equal(dim(pop3),c(2,2)) #the error point still left
  
  #the traits information should be individual level and equal length
  trait=data.frame(dbh=1:N,height=N:1)
  expect_error(population(species=sp1,x=x,y=y,plotdim=c(100,200),traits=c(dbh=1:N)),
               "the given traits is not a data frame")
  expect_error(population(species=sp1,x=x,y=y,plotdim=c(100,200),traits=trait[-1,]),
               "the number of trait row does not equal to the number of individuals")
  pop4=population(species=sp1,x,y,plotdim = c(100,200),traits=trait)
  expect_equal(dim(pop4),c(N,dim(trait)[2]+2))
  expect_true("dbh" %in% colnames(pop4))
  expect_true("height" %in% colnames(pop4))
  
  expect_equal(get_trait_names(pop4),c("dbh","height")) #test the trait names
  expect_equal(get_traits(pop4,get_trait_names(pop4)),trait)
  
  #test remove trait information
  expect_warning(remove_traits(pop4,"dbhs"),
                 "no corresponding trait names have been found")
  expect_warning(remove_traits(pop4,c("dbhs","dbh")),
                 "some trait names were not found")
  expect_equal(get_trait_names(remove_traits(pop4,"dbh")),"height")
  expect_equal(get_trait_names(remove_traits(pop4,"height")),"dbh")
  expect_equal(get_trait_names(remove_traits(pop4,c("height","dbh"))),character()) #no trait founded
  
  })


test_that("subset a population object",{
  pop=population(species=sp1,x=x,y=y,plotdim=c(100,200),traits=data.frame(dbh=1:N))
  
  #the subset.community function
  seli=sample(1:N,5)
  subpop=subset(pop,seli)
  
  expect_is(subpop,"population")
  expect_equal(dim(subpop),c(5,3))
  expect_equal(subpop$x,pop$x[seli])
  expect_equal(subpop$y,pop$y[seli])
  expect_is(attr(subpop,"species"),"character")
  expect_equal(attr(subpop,"species"), attr(subpop,"species"))
  expect_equal(subpop$dbh,pop$dbh[seli])
  
  #remove certain individuals from a population
  ind_i=sample(1:N,10)
  subpop4=remove_individuals(pop,ind_i)
  expect_equal(nrow(subpop4),N-10)
  expect_equal(subpop4$x,pop$x[-ind_i]) # order of coordinates should not change
  expect_equal(subpop4$y,pop$y[-ind_i])
  # order of the species should be equal too
  expect_equal(attr(subpop4,"species"),attr(pop,"species"))
  
  #remove spatially overlapped individuals
  expect_warning(pop <- population(x=c(1,1,2),  y=c(3,3,2),species=sp1,plotdim=c(10,10)))
  expect_true(is_overlapped(pop))
  expect_length(io<-get_overlapped(pop),1)
  expect_equal(io[[1]],c(1,2)) #get the correct index of overlapped individuals
  expect_equal(nrow(uniqueness(pop)),2) #only to individuals left
  
  #if no overlap individual exist, just retrun the orginal object
  pop2=uniqueness(pop)
  expect_equal(uniqueness(pop2),pop2)
})


test_that("merge populations into a community",{
  #merge two populations
  pop1=population("sp1",x=1:10,y=1:10,plotdim=c(100,100))
  pop2=population("sp2",x=11:22,y=11:22,plotdim=c(100,100))
  
  com1=merge(pop1,pop2)
  expect_is(com1,"community") #the new object is a community
  expect_equal(nrow(com1),nrow(pop1)+nrow(pop2)) #no individual is droped
  expect_equal(levels(com1$species),c("sp1","sp2")) #contain two species
  expect_equal(as.numeric(table(com1$species)),c(nrow(pop1),nrow(pop2))) #each species have the unchanged individuals
  
  #merge a list of populations
  com=community(1:10,x=1:10,y=1:10,plotdim=c(10,10))
  pops=split(com)
  com_back=lmerge(pops)
  expect_is(com_back,"community")
  expect_equal(levels(com_back$species),levels(com$species))
  expect_equal(sort(com_back$species),sort(com$species))
  expect_equal(sort(com_back$x),sort(com$x))
  expect_equal(sort(com_back$y),sort(com$y))
  
  #merge two communities with equal traits
  pop3=pop1
  pop1=population("sp1",x=1:10,y=1:10,plotdim=c(100,100),traits = data.frame(dbh=1:10,height=1:10))
  pop2=population("sp2",x=11:22,y=11:22,plotdim=c(100,100),traits = data.frame(dbh=1:12,height=1:12))
  
  #two populations with different columns can not be merged
  expect_error(merge(pop1,pop3),
               "Two different structured populations can not be merged")
  
  com=merge(pop1,pop2)
  expect_is(com,"community")
  expect_equal(dim(com),c(10+12,5)) #has one trait column
  expect_equal(colnames(com)[4],"dbh")
  expect_equal(colnames(com)[5],"height")

})